package penguin.rpc;

import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ExceptionEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import penguin.rpc.dto.RpcDTO;
import penguin.serialize.hessian.HessianClient;
import penguin.transfer.TransferListener;
import penguin.transfer.dto.TransferDTO;
import penguin.transfer.netty.server.NettyServer;

import java.io.PrintWriter;
import java.io.StringWriter;


/**
 * Created on 15/7/4 下午3:20
 *
 * @author 王建华(penguin83@126.com)
 */
public class RpcServer implements TransferListener{

    private static final Logger LOGGER = LoggerFactory.getLogger(RpcServer.class);


    private int port;
    private NettyServer nettyServer;
    private RpcHandler rpcHandler;
    private RpcListener rpcListener;

    public  void init(){
        this.nettyServer = new NettyServer(port,this);
    }

    public void connected(String hostAddress, int port) {
        LOGGER.info("remote connected:["+hostAddress+":"+port+"]");
        if(rpcListener != null){
            rpcListener.connected(hostAddress,port);
        }
    }

    public void disConnected(String hostAddress, int port) {
        LOGGER.info("remote disConnected:["+hostAddress+":"+port+"]");
        if(rpcListener != null){
            rpcListener.disConnected(hostAddress, port);
        }
    }

    public void receiveMessage(Channel channel, Object object) {
        TransferDTO transferParamDTO = (TransferDTO)object;
        RpcDTO rpcDTO = (RpcDTO)transferParamDTO.getObject();

        Object result = null;
        TransferDTO transferResultDTO = TransferDTO.buildMessage(result);
        try {
            result = rpcHandler.invoke(rpcDTO);
            transferResultDTO.setObject(result);
        }
        catch (Exception e) {
            LOGGER.error(rpcDTO.toString(),e);
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            e.printStackTrace(pw);
            transferResultDTO.setObject(sw.toString());
            transferResultDTO.setHasException(true);
        }
        transferResultDTO.setUuid(transferParamDTO.getUuid());
        channel.write(transferResultDTO);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {

    }

    public RpcHandler getRpcHandler() {
        return rpcHandler;
    }

    public void setRpcHandler(RpcHandler rpcHandler) {
        this.rpcHandler = rpcHandler;
    }



    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public RpcListener getRpcListener() {
        return rpcListener;
    }

    public void setRpcListener(RpcListener rpcListener) {
        this.rpcListener = rpcListener;
    }
}
